package com.cqan.httpclient;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class WindowMain {

	private JFrame frame;
	private JTextField requestUrl;
	private JTable paramtable;
	private JTable headertable;
	private JEditorPane bodyediter;
	private JComboBox requestMethod;
	private JButton submitButton;
	private JEditorPane resultConsole;
	private static  HttpRequestClient client;
	
	private static final int WIDTH = 600;
	private static final int HEIGHT = 700;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					WindowMain window = new WindowMain();
					client = new HttpRequestClient(window);
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public WindowMain() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		Image icon = Toolkit.getDefaultToolkit().getImage("../../log.png");
		frame.setIconImage(icon);
		frame.setTitle("HTTP模拟请求工具");
		 Toolkit kit = Toolkit.getDefaultToolkit(); // 定义工具包
		 Dimension screenSize = kit.getScreenSize(); // 获取屏幕的尺寸
		 int screenWidth = screenSize.width/2; // 获取屏幕的宽
		 int screenHeight = screenSize.height/2; // 获取屏幕的高
		 frame.setLocation(screenWidth-WIDTH/2, screenHeight-HEIGHT/2);
		 frame.setSize(new Dimension(WIDTH, HEIGHT));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new FlowLayout());
		JMenuBar menuBar = new JMenuBar();
		frame.setJMenuBar(menuBar);

		JMenu menu = new JMenu("文件");
		menuBar.add(menu);

		JMenuItem open = new JMenuItem("打开",KeyEvent.VK_O);
		JMenuItem save = new JMenuItem("保存",KeyEvent.VK_S);
		JMenuItem exit = new JMenuItem("退出");
		
		exit.setMnemonic(KeyEvent.VK_ESCAPE);
		
		open.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser jChooser = new JFileChooser();
				jChooser.addChoosableFileFilter(new XmlFileFilter());
				 jChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);//只能打开文件夹
				 jChooser.setDialogType(JFileChooser.OPEN_DIALOG);
				    //打开一个对话框
				    int index = jChooser.showDialog(null, "打开");
				    if (index == JFileChooser.APPROVE_OPTION) {
				    	try {
							File file = jChooser.getSelectedFile();
							SAXReader reader = new SAXReader( );
							Document doc = reader.read(file);
							Element root = (Element) doc.selectSingleNode("request");
							if (root!=null) {
								String uri = root.attributeValue("uri");
								String method = root.attributeValue("method");
								List<Element> params = root.selectNodes("params/param");
								if (params!=null&&params.size()>0) {
									DefaultTableModel model = (DefaultTableModel) paramtable.getModel();
									int columnNum = model.getColumnCount();
									while (columnNum>0) {
										model.removeRow(--columnNum);
									}
									for (Element element : params) {
										Vector<String> v = new Vector<String>();
										v.add(element.attributeValue("key"));
										v.add(element.attributeValue("value"));
										model.addRow(v);
									}
									model.addRow(new Vector<String>());
								}
								List<Element> headers = root.selectNodes("headers/param");
								if (headers!=null&&headers.size()>0) {
									DefaultTableModel model = (DefaultTableModel) headertable.getModel();
									int columnNum = model.getColumnCount();
									while (columnNum>0) {
										model.removeRow(--columnNum);
									}
									for (Element element : headers) {
										Vector<String> v = new Vector<String>();
										v.add(element.attributeValue("key"));
										v.add(element.attributeValue("value"));
										model.addRow(v);
									}
									model.addRow(new Vector<String>());
								}
								requestUrl.setText(uri);
								bodyediter.setText(root.elementText("body"));
								requestMethod.setSelectedItem(method);
							}
							
						} catch (Exception e1) {
							JOptionPane.showMessageDialog(jChooser,"保存失败！","提示",JOptionPane.ERROR_MESSAGE);
							e1.printStackTrace();
						}
				    }
			}
		});
		save.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JFileChooser jChooser = new JFileChooser();
				jChooser.setDialogType(JFileChooser.SAVE_DIALOG);
				jChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);//只能打开文件夹
				//打开一个对话框
				int index = jChooser.showDialog(null, "保存");
				if (index == JFileChooser.APPROVE_OPTION) {
					//把获取到的文件的绝对路径显示在文本编辑框中
					File file = jChooser.getSelectedFile();
					String method = requestMethod.getSelectedItem().toString();
					Map<String,String> params = getParams(paramtable);
					Map<String,String> headers = getParams(headertable);
					Document doc = saveConfig(requestUrl.getText(), method, params, headers, bodyediter.getText());
					try {
						XMLWriter output = new XMLWriter(new FileWriter( file));
						output.write(doc);
						output.close();
						JOptionPane.showMessageDialog(jChooser,"保存成功！","提示",JOptionPane.INFORMATION_MESSAGE);
					} catch (IOException e1) {
						JOptionPane.showMessageDialog(jChooser,"保存失败！","提示",JOptionPane.ERROR_MESSAGE);
						e1.printStackTrace();
					}
				}
			}
		});
		exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
				menu.add(open);
		menu.add(save);
		menu.add(exit);

		JMenu menu_1 = new JMenu("帮助");
		menuBar.add(menu_1);

		JMenu menu_2 = new JMenu("关于");
		menu_1.add(menu_2);
		JPanel panel = new JPanel();
		panel.setSize(600,40);
		panel.setBorder(new CompoundBorder(new EmptyBorder(1, 1, 1, 1), null));
		frame.getContentPane().add(panel);

		JLabel label = new JLabel("请求地址:");
		label.setHorizontalAlignment(SwingConstants.LEFT);
		panel.add(label);

		requestUrl = new JTextField();
		requestUrl.setToolTipText("输入请求地址");
		requestUrl.setPreferredSize(new Dimension(550, 27));
		requestUrl.setText("http://");
		panel.add(requestUrl);
		requestUrl.setColumns(35);
		
		requestMethod = new JComboBox();
		requestMethod.addItem("GET");
		requestMethod.addItem("POST");
		requestMethod.addItem("PUT");
		requestMethod.addItem("DELETE");
		panel.add(requestMethod);

		
		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		
		paramtable = createParamTable();
		JScrollPane requestPanel = new JScrollPane(paramtable);
		tabbedPane.addTab("POST参数", requestPanel);
		
		
		bodyediter = new JEditorPane();
		JScrollPane bodyPanel = new JScrollPane(bodyediter);
		tabbedPane.addTab("请求Body",bodyPanel);
		
		headertable = createHeaderTable();
		JScrollPane headerPanel = new JScrollPane(headertable);
		tabbedPane.addTab("header", headerPanel);
		
		
		tabbedPane.setPreferredSize(new Dimension(585,260));
		frame.getContentPane().add(tabbedPane);
		
		Panel console = new Panel();
		resultConsole = new JEditorPane("text/plain","result");
		resultConsole.setText("result：");
		resultConsole.setEditable(false);
		JScrollPane resultPanel = new JScrollPane(resultConsole);
		resultPanel.setPreferredSize(new Dimension(580, 280));
		console.add(resultPanel);
		
		Panel op = new Panel();
		submitButton = new JButton("提交");
		submitButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				resultConsole.setText("");
				//paramTableModel.addRow(new Vector());
				//submitButton.setEnabled(false);
				String method = requestMethod.getSelectedItem().toString();
				Map<String,String> params = getParams(paramtable);
				Map<String,String> headers = getParams(headertable);
				if ("POST".equals(method)) {
					client.post(requestUrl.getText(),params, bodyediter.getText(), headers);
				}
				if ("GET".equals(method)) {
					client.get(requestUrl.getText(),params, bodyediter.getText(), headers);
				}
				if ("PUT".equals(method)) {
					client.put(requestUrl.getText(),params, bodyediter.getText(), headers);
				}
				if ("DELETE".equals(method)) {
					client.get(requestUrl.getText(),params, bodyediter.getText(), headers);
				}
			}
		});
		op.add(submitButton);
		op.setPreferredSize(new Dimension(600, 80));
		console.add(op);
		console.setPreferredSize(new Dimension(595, 400));
		frame.getContentPane().add(console);
	}

	private JTable createParamTable() {
		JTable param = new JTable();
		param.setRowHeight(20);
		param.setModel(initTableModel("参数名称","参数值"));
		param.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				JTable jt = (JTable) e.getSource();
				DefaultTableModel model = (DefaultTableModel) jt.getModel();
				int rowCount = model.getRowCount();
				int paramNum = 1;
				Vector<Vector<String>> vector = model.getDataVector();
				Iterator<Vector<String>> it = vector.iterator();
				while (it.hasNext()) {
					Vector<String> v = it.next();
					String paramName =  v.get(0);
					if (paramName!=null&&!"".equals(paramName.trim())) {
						paramNum++;
					}
				}
				if (rowCount==paramNum) {
					model.addRow(new Vector());
				}
			}
		});
		return param;
	}
	
	private TableModel initTableModel(String ... params){
		Vector<Vector<String>> rows = new Vector<Vector<String>>();
		rows.add(new Vector<String>());
		rows.add(new Vector<String>());
		Vector<String> columns = new Vector<String>();
		for (String column : params) {
			columns.add(column);
		}
		return new DefaultTableModel(rows,columns);
	}
	private JTable createHeaderTable() {
		JTable param = new JTable();
		param.setRowHeight(20);
		param.setModel(initTableModel("Header名称","Header值"));
		
		param.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				JTable jt = (JTable) e.getSource();
				DefaultTableModel model = (DefaultTableModel) jt.getModel();
				int rowCount = model.getRowCount();
				int paramNum = 1;
				Vector<Vector<String>> vector = model.getDataVector();
				Iterator<Vector<String>> it = vector.iterator();
				while (it.hasNext()) {
					Vector<String> v = it.next();
					String paramName =  v.get(0);
					if (paramName!=null&&!"".equals(paramName.trim())) {
						paramNum++;
					}
				}
				if (rowCount==paramNum) {
					model.addRow(new Vector());
				}
			}
		});
		return param;
	}
	
	public void setResult(String content,boolean add){
		if (add) {
			resultConsole.setText(resultConsole.getText()+"\n"+content);
		}else {
			resultConsole.setText(content);
		}
		submitButton.setEnabled(true);
		System.out.println("2222");
	}
	
	@SuppressWarnings("unchecked")
	private Map<String,String> getParams(JTable table){
		Map<String,String> params = new HashMap<String, String>();
		
		DefaultTableModel model = (DefaultTableModel) table.getModel();
		Vector<Vector<String>> voctor = model.getDataVector();
		Iterator<Vector<String>> it = voctor.iterator();
		while (it.hasNext()) {
			Vector<String> v = it.next();
			String paramName =  v.get(0);
			if (paramName!=null&&!"".equals(paramName.trim())) {
				params.put(v.get(0), v.get(1));
			}
		}
		return params;
	}
	
	private  Document saveConfig(String uri,String method,Map<String, String> params,Map<String, String> headers,String body){
		
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("request");
		root.addAttribute("uri", uri).addAttribute("method", method);
		
		Element reqParam = root.addElement("params");
		Set<Map.Entry<String, String>> entry = params.entrySet();
		Iterator<Entry<String, String>> it = entry.iterator();
		while (it.hasNext()) {
			Element param = reqParam.addElement("param");
			Entry<String, String>  e =it.next();
			param.addAttribute("key", e.getKey());
			param.addAttribute("value", e.getValue());
		}
		
		Element headerParam = root.addElement("headers");
		Set<Map.Entry<String, String>> hentry = headers.entrySet();
		Iterator<Entry<String, String>> iterator = hentry.iterator();
		while (iterator.hasNext()) {
			Element hparam = headerParam.addElement("param");
			Entry<String, String>  e =  iterator.next();
			hparam.addAttribute("key",e.getKey());
			hparam.addAttribute("value", e.getValue());
		}
		
		Element reqBody = root.addElement("body");
		reqBody.setText(body);
		return doc;
	}

	private class XmlFileFilter extends  FileFilter {
		
		@Override
		public String getDescription() {
			return "*.xml(xml文件)";
		}
		
		@Override
		public boolean accept(File f) {
			String fileName = f.getName();
			return fileName.toLowerCase().endsWith(".xml");
		}
	}

}


